/*******************************************************************************
 * Copyright (c) Jonathan Buck - jonbuck16@gmail.com
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    jonbuck16@gmail.com - initial API and implementation
 *******************************************************************************/
package net.jonbuck.tassoo.ui.view;

import net.jonbuck.tassoo.chart.ui.canvas.ChartCanvas;
import net.jonbuck.tassoo.chart.ui.chart.AbstractChartBuilder;
import net.jonbuck.tassoo.chart.ui.chart.PieChartBuilder;
import net.jonbuck.tassoo.chart.ui.data.TaskStatusDataSet;
import net.jonbuck.tassoo.eventmanager.EventManager;
import net.jonbuck.tassoo.eventmanager.EventManagerImpl;
import net.jonbuck.tassoo.eventmanager.events.TaskStoreClosedEvent;
import net.jonbuck.tassoo.eventmanager.events.TaskStoreOpenedEvent;
import net.jonbuck.tassoo.eventmanager.listener.TaskStoreClosedListener;
import net.jonbuck.tassoo.eventmanager.listener.TaskStoreOpenedListener;
import net.jonbuck.tassoo.model.Container;
import net.jonbuck.tassoo.persistence.dao.TassooDaoImpl;

import org.apache.commons.lang.StringUtils;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.util.EContentAdapter;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.forms.widgets.Form;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Section;
import org.eclipse.ui.part.ViewPart;

/**
 * 
 * 
 * @since 1.0.0
 */
public class StatisticsView extends ViewPart implements TaskStoreOpenedListener, TaskStoreClosedListener {

	/**
	 * <p>
	 * <b>Observes changes to the model so that the charts in the statistics
	 * view can be updated as the model changes.</b>
	 * </p>
	 * 
	 * @since 1.0.0
	 */
	private class ModelObserver extends EContentAdapter {
		public void notifyChanged(Notification notification) {
			int eventType = notification.getEventType();
			Object obj = notification.getFeature();
			if (obj instanceof EReference) {
				EReference object = (EReference) obj;
				if (object != null && StringUtils.equalsIgnoreCase(object.getName(), "task")) {
					switch (eventType) {
					case Notification.ADD:
					case Notification.ADD_MANY:
					case Notification.REMOVE:
					case Notification.REMOVE_MANY:
						updateCharts();
						break;
					}
				} else if (object != null && StringUtils.equalsIgnoreCase(object.getName(), "status")) {
					switch (eventType) {
					case Notification.SET:
						updateCharts();
						break;
					}
				}
			}
			super.notifyChanged(notification);
		}
	}

	/** ..TODO.. */
	private AbstractChartBuilder builder = null;

	/** ..TODO.. */
	private Container container;

	/** ..TODO.. */
	private EventManager eventManager = EventManagerImpl.getInstance();

	/** ..TODO.. */
	ModelObserver modelObserver = new ModelObserver();

	/** ... */
	private ChartCanvas pieChartCanvas;

	/**
	 * Listens for changes in the workbench and then
	 */
	private ISelectionListener selectionListener = new ISelectionListener() {
		public void selectionChanged(IWorkbenchPart part, ISelection selection) {
			if (!(selection instanceof IStructuredSelection)) {
				return;
			}
			IStructuredSelection ss = (IStructuredSelection) selection;
			Object obj = ss.getFirstElement();
			if (obj instanceof Container) {
				setContainer((Container) obj);
				updateCharts();
			}
		}
	};

	/**
	 * 
	 */
	public StatisticsView() {

	}

	/**
	 * 
	 */
	public void createPartControl(Composite parent) {
		parent.setLayout(GridLayoutFactory.fillDefaults().create());
		parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

		FormToolkit toolkit = new FormToolkit(parent.getDisplay());
		Form statisticsForm = toolkit.createForm(parent);
		statisticsForm.setLayout(new GridLayout());
		statisticsForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

		statisticsForm.getBody().setLayout(new GridLayout());
		statisticsForm.getBody().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

		// Creating the Screen
		Section section = toolkit.createSection(statisticsForm.getBody(), Section.EXPANDED | Section.DESCRIPTION
				| Section.TITLE_BAR);
		section.setText("Tasks By Status"); //$NON-NLS-1$
		section.setDescription("Shows the number of tasks by status"); //$NON-NLS-1$
		section.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

		Composite client = toolkit.createComposite(section, SWT.WRAP);
		client.setLayout(new GridLayout());
		client.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

		pieChartCanvas = new ChartCanvas(client, SWT.NONE);
		pieChartCanvas.setLayout(new GridLayout());
		pieChartCanvas.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

		section.setClient(client);

		// Creating the Screen
		Section tasksByPriority = toolkit.createSection(statisticsForm.getBody(), Section.EXPANDED | Section.DESCRIPTION
				| Section.TITLE_BAR);
		tasksByPriority.setText("Tasks By Priority"); //$NON-NLS-1$
		tasksByPriority.setDescription("Shows the number of tasks by priority"); //$NON-NLS-1$
		tasksByPriority.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

		Composite tasksByPriorityClient = toolkit.createComposite(tasksByPriority, SWT.WRAP);
		tasksByPriorityClient.setLayout(new GridLayout());
		tasksByPriorityClient.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

		tasksByPriority.setClient(tasksByPriorityClient);

		getSite().getPage().addSelectionListener(selectionListener);
	}

	/**
	 * 
	 */
	public void init(IViewSite site, IMemento memento) throws PartInitException {
		super.init(site, memento);
		eventManager.addListener(TaskStoreOpenedEvent.class, this);
		eventManager.addListener(TaskStoreClosedEvent.class, this);
		TassooDaoImpl.getInstance().addModelListener(modelObserver);
	}

	/**
	 * 
	 */
	public void processTaskStoreClosedEvent() {
		TassooDaoImpl.getInstance().removeModelListener(modelObserver);
	}

	/**
	 * 
	 */
	public void processTaskStoreOpenedEvent() {
		TassooDaoImpl.getInstance().addModelListener(modelObserver);
	}

	protected void setContainer(Container container) {
		this.container = container;

	}

	/**
	 * 
	 */
	public void setFocus() {

	}

	private void updateCharts() {
		if (builder == null) {
			builder = new PieChartBuilder(new TaskStatusDataSet(container));
			pieChartCanvas.setChart(builder.build());
		} else {
			pieChartCanvas.setChart(builder.refreshData(new TaskStatusDataSet(container)));
			pieChartCanvas.chartRefresh();
		}
	}

}
